/******************************************************************************
 * @File name   :      PurchasePackageServiceImpl.java
 *
 * @Author      :      JIZHANGS
 *
 * @Date        :      Jul 24, 2015
 *
 * @Copyright Notice: 
 * Copyright (c) 2015 Capgemini, Inc. All  Rights Reserved.
 * This software is published under the terms of the Capgemini Software
 * License version 1.0, a copy of which has been included with this
 * distribution in the LICENSE.txt file.
 * 
 * 
 * ----------------------------------------------------------------------------
 * Date                   Who         Version        Comments
 * Jul 24, 2015 1:26:18 PM        JIZHANGS     1.0            Initial Version
 *****************************************************************************/
package com.cap.bts.crmdp.dealer.purchase.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cap.bts.commonfunc.common.util.UserUtil;
import com.cap.bts.crmdp.dealer.activation.dao.IPackageRedemptionLinesDao;
import com.cap.bts.crmdp.dealer.activation.dao.IPackageRedemptionLinesItemDao;
import com.cap.bts.crmdp.dealer.activation.domain.PackageRedemptionLines;
import com.cap.bts.crmdp.dealer.activation.dto.ActivationQueryDto;
import com.cap.bts.crmdp.dealer.activation.service.IActivationService;
import com.cap.bts.crmdp.dealer.coupon.constants.CouponConstants;
import com.cap.bts.crmdp.dealer.coupon.dao.ITicketLineDefineDao;
import com.cap.bts.crmdp.dealer.coupon.dao.ITicketPriceOfDealerDao;
import com.cap.bts.crmdp.dealer.coupon.domain.TicketLine;
import com.cap.bts.crmdp.dealer.coupon.domain.TicketPriceOfDealer;
import com.cap.bts.crmdp.dealer.mars.domain.PackageRedemptionLinesItem;
import com.cap.bts.crmdp.dealer.mars.service.IMarsActivationService;
import com.cap.bts.crmdp.dealer.member.dao.IMaintainCarPlateDao;
import com.cap.bts.crmdp.dealer.member.domain.CarPlateInfo;
import com.cap.bts.crmdp.dealer.member.service.IMaintainMemberService;
import com.cap.bts.crmdp.dealer.purchase.constants.PurchaseConstants;
import com.cap.bts.crmdp.dealer.purchase.dao.ICardInventoryDao;
import com.cap.bts.crmdp.dealer.purchase.dao.IMemberPackageDao;
import com.cap.bts.crmdp.dealer.purchase.dao.IPackageDefinitionDao;
import com.cap.bts.crmdp.dealer.purchase.domain.CardInventory;
import com.cap.bts.crmdp.dealer.purchase.domain.MemberPackageInfo;
import com.cap.bts.crmdp.dealer.purchase.domain.PackageDefinition;
import com.cap.bts.crmdp.dealer.purchase.domain.PackageInventory;
import com.cap.bts.crmdp.dealer.purchase.dto.MemberPackageInfoSubmitDto;
import com.cap.bts.crmdp.dealer.purchase.service.IPurchasePackageService;
import com.cap.bts.crmdp.dealer.redemption.dao.IPackageRedemptionDao;
import com.cap.bts.crmdp.dealer.redemption.domain.MemberPackageRedemption;
import com.cap.bts.framework.common.exception.AppException;
import com.cap.bts.framework.common.service.impl.BaseServiceImpl;

/**
*
*/
@Transactional(rollbackFor = AppException.class)
@Service
public class PurchasePackageServiceImpl extends BaseServiceImpl implements IPurchasePackageService {
    
    private static final Logger LOGGER = Logger.getLogger(PurchasePackageServiceImpl.class);
    
    private static final String  PURCHASE_PACKAGE = "purchasePackage";
    
    @Resource(name = "memberPackageDao")
    private IMemberPackageDao memberPackageDao;
    
    @Resource(name = "maintainCarPlateDao")
    IMaintainCarPlateDao maintainCarPlateDao;
    
    @Resource(name = "packageDefinitionDao")
    IPackageDefinitionDao  packageDefinitionDao;
    
    @Resource(name = "cardInventoryDao")
    ICardInventoryDao cardInventoryDao;
    
    @Resource(name = "packageRedemptionLinesDao")
    IPackageRedemptionLinesDao packageRedemptionLinesDao;
    
    @Resource(name = "packageRedemptionDao")
    private IPackageRedemptionDao memberPackageRedemptionDao;
    
    @Autowired
    IActivationService activationService;
    
    @Autowired
    IMarsActivationService marsActivationService;
    
    @Autowired
    IMaintainMemberService maintainMemberService;
    
    @Autowired
    ITicketLineDefineDao iTicketLineDefineDao;
    
    @Autowired
    ITicketPriceOfDealerDao     ticketPriceOfDealerDao;
    
    @Autowired
    IPackageRedemptionLinesItemDao packageRedemptionLinesItemDao;
    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      Jul 24, 2015
     * @see com.cap.bts.crmdp.dealer.purchase.service.IPurchasePackageService#purchasePackage(com.cap.bts.crmdp.dealer.purchase.dto.MemberPackageInfoSubmitDto)
    **/
    @Override
    public void purchasePackage(MemberPackageInfoSubmitDto dto) throws AppException {
        PackageInventory pi=new PackageInventory();
        MemberPackageInfo mpi=new MemberPackageInfo();
        if(dto.getOnhandQuantity() <=0 && !dto.isGiftPurchase()){
            LOGGER.error("Quantity Exception");
            throw new AppException("purchasePackage","Quantity Exception");
        }
        pi.setDealerId(dto.getDealerId());
        pi.setPackageDefId(dto.getPackageDefId());
        PackageDefinition packageDefinition=packageDefinitionDao.getPackageDefinitionInfoById(dto.getPackageDefId());
        
        if(!dto.isGiftPurchase()){
            CardInventory ci=cardInventoryDao.getCardInventoryInfo(packageDefinition.getCardDefinition().getId(), dto.getDealerId());
            ci.setOnhandQuantity(ci.getOnhandQuantity()-1);
        }
        //减少库存
        mpi.setMemberId(dto.getMemberId());
        //设置carid
        List<CarPlateInfo> carlist =maintainCarPlateDao.getCarPlateInfoListByCarPlateOrMemberId(dto.getCarPlate(), dto.getMemberId());
        if(carlist!=null && !carlist.isEmpty()){
            mpi.setCarId(carlist.get(0).getId());
        }
        PackageDefinition pd=new PackageDefinition();
        pd.setId(dto.getPackageDefId());
        mpi.setPackageDefinition(pd);
        mpi.setDealerId(dto.getDealerId());
        mpi.setStatus((byte)PurchaseConstants.PACKAGE_STATUS_SALED);
        mpi.setPurchaseDate(new Date());
        mpi.setActualPrice(dto.getPrice());
        mpi.setMarsLockStatus(0);
        mpi.setCardDefinition(packageDefinition.getCardDefinition());
        if (dto.getIsPhysicalCard()==PurchaseConstants.FHYSICAL_CARD) {
        	if (dto.getPackageNumber() == null || "".equals(dto.getPackageNumber())) {
                throw new AppException(PURCHASE_PACKAGE, "PackageNumber Empty");
            }
            MemberPackageInfo memberPackageInfocheck=memberPackageDao.getMemeberPackageInfoByPackageNumber(dto.getPackageNumber());
            if(packageDefinition.getCardDefinition().getId()!=memberPackageInfocheck.getCardDefinition().getId()){
                    throw new AppException(PURCHASE_PACKAGE, "卡号与套餐类型不匹配！");
            }
            
            //实物卡时
            mpi.setPackageNumber(dto.getPackageNumber());
            memberPackageDao.updateMemberPackageInfo(mpi);
            //将激活时插入redemption表的逻辑转移到购买时
            ActivationQueryDto actDto=new ActivationQueryDto();
            actDto.setPackageNumber(mpi.getPackageNumber());
            actDto.setPackageActiveCode(mpi.getActivationCode());
            MemberPackageInfo memberPackageInfo = memberPackageDao.getMemberPackageInfoByActivationDto(actDto);
            if (memberPackageInfo != null) {
                insertRedemForPurchasePackage(memberPackageInfo, dto.getPackageDefId());
            }
        }else{
            //非实物卡时
            try {
                mpi=memberPackageDao.addMemberPackageInfo(mpi);
            } catch (AppException e) {
                LOGGER.error("purchasePackage", e);
                throw new AppException("purchasePackage", e.getMessage());
            }
            
            //激活业务处理
            ActivationQueryDto aqDto=new ActivationQueryDto();
            aqDto.setActiveMemberId(dto.getMemberId());
            aqDto.setCarPlate(dto.getCarPlate());
            aqDto.setPackageNumber(mpi.getPackageNumber());
            aqDto.setPackageDefId(dto.getPackageDefId());
            aqDto.setPackageActiveCode(mpi.getActivationCode());
            aqDto.setMobilePhone(dto.getMobilePhone());
            aqDto.setMemberName(dto.getMemberName());
            aqDto.setGiftPurchase(dto.isGiftPurchase());
            MemberPackageInfo memberPackageInfo = memberPackageDao.getMemberPackageInfoByActivationDto(aqDto);
            if (memberPackageInfo != null) {
                insertRedemForPurchasePackage(memberPackageInfo, dto.getPackageDefId());
            }
            activationService.saveMemberActivation(aqDto);
        }
    }
    
    
    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      Aug 5, 2015
     * @see com.cap.bts.crmdp.dealer.purchase.service.IPurchasePackageService#getNonPhysicalCardNumber(com.cap.bts.crmdp.dealer.purchase.domain.MemberPackageInfo)
    **/
    @Override
    public String getNonPhysicalCardNumber(Long packageDefId) throws AppException {
        return memberPackageDao.getNonPhysicalCardNumber(packageDefId);
    }


    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      2015年11月17日
     * @see com.cap.bts.crmdp.dealer.purchase.service.IPurchasePackageService#checkPurchasePackage(com.cap.bts.crmdp.dealer.purchase.dto.MemberPackageInfoSubmitDto)
    **/
    @Override
    public boolean checkPurchasePackage(Long memberId,Long packageDefId,Long carId,Long dealerId) throws AppException {
        if(packageDefId != null){
            PackageDefinition packageDefinition = packageDefinitionDao.getPackageDefinitionInfoById(packageDefId);
            if(packageDefinition == null){
                throw new AppException("packageDefinitionError", "套餐不存在");
            }
            Long numberSequence = 0L;
           if(numberSequence.equals(packageDefinition.getNumberSequence())){
               return true;
           }
           int num = memberPackageDao.getPackagePurchaseNumWithPackageCode(dealerId, memberId, carId, packageDefId);
           if(packageDefinition.getNumberSequence().intValue() - num >0){
               return true;
           }
        }
        return false;
    }


    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      2015年11月17日
     * @see com.cap.bts.crmdp.dealer.purchase.service.IPurchasePackageService#checkPurchasePackage(java.lang.Long, java.lang.Long, java.lang.String, java.lang.Long)
    **/
    @Override
    public boolean checkPurchasePackage(Long memberId, Long packageDefId, String carPlate,
        Long dealerId) throws AppException {
        if(packageDefId != null){
            PackageDefinition packageDefinition = packageDefinitionDao.getPackageDefinitionInfoById(packageDefId);
            if(packageDefinition == null){
                throw new AppException("packageDefinitionError", "套餐不存在");
            }
            Long numberSequence = 0L;
           if(numberSequence.equals(packageDefinition.getNumberSequence())){
               return true;
           }
           Long carId = 0L;
           List<CarPlateInfo> carlist =maintainCarPlateDao.getCarPlateInfoListByCarPlateOrMemberId(carPlate, memberId);
           if(carlist!=null && !carlist.isEmpty()){
               carId = carlist.get(0).getId();
           }
           int num = memberPackageDao.getPackagePurchaseNumWithPackageCode(dealerId, memberId, carId, packageDefId);
           if(packageDefinition.getNumberSequence().intValue() - num >0){
               return true;
           }
        }
        return false;
    }


    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      2015年11月19日
     * @see com.cap.bts.crmdp.dealer.purchase.service.IPurchasePackageService#insertRedemForPurchasePackage(com.cap.bts.crmdp.dealer.activation.dto.ActivationQueryDto)
    **/
    @Override
    public void insertRedemForPurchasePackage(MemberPackageInfo memberPackageInfo, Long packageDefId) throws AppException {
        ActivationQueryDto dto = new ActivationQueryDto();
        dto.setPackageDefId(packageDefId);
        List<PackageRedemptionLines> packageRedemptionLinesList = packageRedemptionLinesDao
            .getPackageRedemptionLinesByDto(dto);
        if (packageRedemptionLinesList != null && !packageRedemptionLinesList.isEmpty()) {
            for (int i = 0; i < packageRedemptionLinesList.size(); i++) {
                // 集成套餐定义时新追加
                // 用ticket定义表来更新RedemptionLine表写入description,hasVerificationCode三个字段
                // description
                PackageRedemptionLines saveLine = packageRedemptionLinesDao
                    .findById(packageRedemptionLinesList.get(i).getId());
                String description = iTicketLineDefineDao
                    .getTicketDescriptionInfoByTicketId(packageRedemptionLinesList.get(i)
                        .getTicket().getId());
                if (description != null) {
                    saveLine.setDescription(description);
                }
                // hasVerificationCode
                if (packageRedemptionLinesList.get(i).getTicket().getVerificationMethod()
                    .equals(CouponConstants.NEED_ACTIVICATION_YES)) {
                    saveLine.setHasVerificationCode("Y");
                } else {
                    saveLine.setHasVerificationCode("N");
                }
                // shortName
                String shortName = packageRedemptionLinesList.get(i).getTicket()
                    .getTicketName();
                saveLine.setShortName(shortName);
                // 保存状态
                packageRedemptionLinesDao.update(saveLine);

                // 逐行添加package明细到MemberPackageRedemption(会员-卡-使用 表)
                PackageRedemptionLines lines = packageRedemptionLinesList.get(i);
                for (int j = 0; j < lines.getNumberOfUse(); j++) {
                    MemberPackageRedemption memberPackageRedemption = new MemberPackageRedemption();
                    memberPackageRedemption.setPackageId(memberPackageInfo.getId());
                    memberPackageRedemption.setPackageRedemptionLine(lines);
                    memberPackageRedemption.setShortName(shortName);
                    if (description != null) {
                        memberPackageRedemption.setDescription(description);
                    }
                    // 验证码
                    memberPackageRedemption.setActivicationCode(String
                        .valueOf((int) (100000 + Math.random() * 1000000)));
                    // 0未使用，1已使用
                    memberPackageRedemption.setStatus(0);

                   MemberPackageRedemption mpr = memberPackageRedemptionDao
                       .save(memberPackageRedemption);
                   
                   //只插入一条，要加入逻辑判断
                   List<TicketLine> itemList = iTicketLineDefineDao
                       .getTicketLineInfoList(lines.getTicket().getId().toString());
                   if((lines.getNumberOfUse()==1||(lines.getNumberOfUse()!=1&&j==0))&&itemList != null && !itemList.isEmpty()){
                           for (TicketLine tl : itemList) {
                               PackageRedemptionLinesItem lineItem = new PackageRedemptionLinesItem();
                               lineItem.setTicket(packageRedemptionLinesList.get(i).getTicket());
                               lineItem.setMemberPackageInfo(memberPackageInfo);
                               lineItem.setMemberPackageRedemption(mpr);
                               lineItem.setItemName(tl.getItemName());
                               lineItem.setTicketLine(tl);
                               
                               lineItem.setPrice(tl.getPrepayAmount()/tl.getQuantity());
                               
                               lineItem.setQuantity(tl.getQuantity());
                               packageRedemptionLinesItemDao.save(lineItem);
                           }
                       }
                   }
                }
            }
        }
}
